#include <buola/gui.h>

#include <buola/widgets/cbutton.h>
#include <buola/widgets/ctheme.h>
#include <buola/gui/cicon.h>

namespace buola { namespace gui {

CButton::CButton()
    :   mPressed(false)
    ,   mPointerInside(false)
{
    SetFocusMode(EFocusMode::TAB);
    SetStyle(BUTTON_TEXT);
    get_default_theme()->PrepareButton(this);
    SetBackColor({0.7,0.7,0.7});
}

CButton::~CButton()
{
}

void CButton::GetPropertyNames(std::vector<std::string> &pNames)
{
    pNames.push_back("small");
    pNames.push_back("disabled");

    CWidget::GetPropertyNames(pNames);
}

void CButton::SetProperty(const std::string &p,const UAny &v)
{
    if(ProcessStyleProperty(p,v,"small",BUTTON_SMALL)) return;
    if(ProcessStyleProperty(p,v,"disabled",STYLE_DISABLED)) return;

    CWidget::SetProperty(p,v);
}

void CButton::SetIconImage(PIcon pIcon)
{
    SetImage(pIcon->GetPixmap(CIcon::SMALL),pIcon->GetPixmap(CIcon::SMALL,CIcon::HIGHLIGHTED));
}

void CButton::SetIconImage(const std::string &pIconName)
{
    SetIconImage(CIcon::Get(pIconName));
}

void CButton::SetImage(const img::CPicture &pNormal,const img::CPicture &pHover,const img::CPicture &pPressed)
{
    mNormalImage=pNormal;
    mHoverImage=pHover;
    mPressedImage=pPressed;

    SetStyle(BUTTON_CONTENTS,BUTTON_IMAGE);

    Refresh();
}

void CButton::SetPicture(const img::CPicture &pNormal,const img::CPicture &pHover,const img::CPicture &pPressed)
{
    mNormalImage=pNormal;
    mHoverImage=pHover;
    mPressedImage=pPressed;

    SetStyle(BUTTON_CONTENTS,BUTTON_PICTURE);

    Refresh();
}

void CButton::SetCaption(const std::wstring &pCaption)
{
    mCaption=pCaption;
    Refresh();
}

///////////////// events //////////////////

void CButton::OnExpose(const CExposeEvent &pE)
{
    get_default_theme()->DrawButton(pE.mGC,this,CTheme::DRAW_NONE);
}

void CButton::OnButtonDown(const CMouseEvent &pE)
{
    if(GetStyle(STYLE_DISABLED)) return;
    if(pE.mButton!=EMouseButton::LEFT) return;

    if(GetStyle(BUTTON_REPEAT))
    {
        ///\todo
        //RepeatButtonEvent(pE,chrono::milliseconds(400),chrono::milliseconds(100));
        ePressed();
    }

    mPressed=true;
    Refresh();
}

void CButton::OnButtonUp(const CMouseEvent &pE)
{
    if(GetStyle(STYLE_DISABLED)) return;
    if(pE.mButton!=EMouseButton::LEFT) return;

    if(!mPressed) return;

    mPressed=false;

    if(GetStyle(BUTTON_REPEAT))
    {
        Refresh();
    }
    else if(mPointerInside)
    {
        Refresh();
        ePressed();
    }
}

void CButton::OnMouseIn(const CMouseEvent &pE)
{
    if(GetStyle(STYLE_DISABLED)) return;
    mPointerInside=true;

    Refresh();
}

void CButton::OnMouseOut(const CMouseEvent &pE)
{
    if(GetStyle(STYLE_DISABLED)) return;
    mPointerInside=false;

    Refresh();
}

void CButton::OnFocusIn(const CFocusEvent &pE)
{
    Refresh();
}

void CButton::OnFocusOut(const CFocusEvent &pE)
{
    Refresh();
}

void CButton::OnKeyDown(const CKeyEvent &pE)
{
    if(GetStyle(STYLE_DISABLED)) return;
    if(pE.mKey==KEY_SPACE)
    {
        mPressed=true;
        mPointerInside=true;
        Refresh();
    }
}

void CButton::OnKeyUp(const CKeyEvent &pE)
{
    if(GetStyle(STYLE_DISABLED)) return;
    if(pE.mKey==KEY_SPACE)
    {
        mPressed=false;
        Refresh();
        ePressed();
    }
}

void CButton::OnStyleChanged(TStyle pOld)
{
    int lChange=pOld^GetStyle();

    if((lChange&STYLE_DISABLED)||(lChange&BUTTON_SMALL))
    {
        if(GetStyle(STYLE_DISABLED))
        {
            mPressed=false;
            mPointerInside=false;
        }
        Refresh();
    }
    if(lChange&STYLE_FAKE)
    {
        if(GetStyle(STYLE_FAKE))
        {
            SetInputMode(EInputMode::MOUSETRANSPARENT);
        }
        else
        {
            SetInputMode(EInputMode::NORMAL);
        }
    }
}

/*namespace gui*/ } /*namespace buola*/ }
